package com.siecom.module;

import android.util.Log;

import com.siecom.algorithm.util.Arrays;
import com.siecom.nativelibs.rkGpioControlNative;
import com.siecom.tool.ByteTool;
import com.siecom.constconfig.ConstDefine;
import com.siecom.constconfig.ErrorDefine;

/**
 * Created by zhq on 2016/10/20.
 */
public class TesoFingerprintModule extends SerialPortModule {
    private static TesoFingerprintModule ourInstance = new TesoFingerprintModule();

    public static TesoFingerprintModule getInstance() {
        return ourInstance;
    }

    private String serialDev;
    private int baudRate = 9600;
    protected boolean isOpen = false;

    private static byte[] sendBuffer = new byte[1024];
    private static byte[] revBuffer = new byte[40960];

    private TesoFingerprintModule() {
    }

    public boolean init() {
        this.serialDev = ConstDefine.getFingerprintPort();
        if(this.serialDev==null){
            isOpen = false;
            return false;
        }
        if (initSerialPort(this.serialDev, this.baudRate)) {
            Log.e("initserial", "open");
            isOpen = true;
            return true;
        }
        return false;
    }

    public int getFeature(byte[] feature,int[] len){
        byte head = 0x64;
        byte[] data = new byte[1];
        data[0]  = 0x02;
        TC_Send(head, data);
        int ret = revPacket(len, 10000);
        System.arraycopy(revBuffer, 8, feature, 0, len[0]);
        return ret;
    }

    public int checkFingerPicture(byte[] temp,int[] len){
        byte head = (byte) 0x80;
        byte[] data = new byte[4];
        data[0] = 0x05;
        data[1] = 0x00;
        data[2] = 0x00;
        data[3] = 0x00;
        TC_Send(head, data);
        int ret = revPacket(len, 60000);
        System.arraycopy(revBuffer, 8, temp, 0, len[0]);
        return ret;

    }

    public int getFingerPicture(byte[] temp,int[] len){
        byte head = (byte) 0x80;
        byte[] data = new byte[4];
        data[0] = 0x00;
        data[1] = 0x01;
        data[2] = 0x0d;
        data[3] = 0x00;
        TC_Send(head, data);
        int ret = revPacket(len, 60000);
        System.arraycopy(revBuffer, 8, temp, 0, len[0]);
        return ret;

    }

    public int templateEnroll(byte[] temp,int[] len){
        byte head = 0x63;
        byte[] data = new byte[1];
        data[0] = 0x00;
        TC_Send(head, data);
        int ret = revPacket(len, 60000);
        System.arraycopy(revBuffer, 8, temp, 0, len[0]);
        return ret;
    }

    public int readVersion(byte[] version, int[] len) {
        byte head = 0x68;
        byte[] data = new byte[0];
        TC_Send(head, data);
        int ret = revPacket(len, 2000);
        System.arraycopy(revBuffer, 8, version, 0, len[0]);
        return ret;
    }


    public int revPacket(int[] pwPacketetLen, int dwTimeoutMs) {

        int wDataLen = -1;
        int byRet = RecvBytes(revBuffer, 0, 1, dwTimeoutMs);

        if ((1 != byRet) || (0x7e != revBuffer[0])) {
            return -1;
        }
        byRet = RecvBytes(revBuffer, 1, 1, dwTimeoutMs);
//        Log.e("rev1", ByteTool.bytearrayToHexString(revBuffer,2));
        if ((1 != byRet) || (0x42 != revBuffer[1])) {
            return -2;
        }
        byRet = RecvBytes(revBuffer, 2, 2, dwTimeoutMs);
//        Log.e("rev2", ByteTool.bytearrayToHexString(revBuffer,4));
        if ((2 != byRet) || (0x00 != revBuffer[3])) {
            return -3;
        }
        byRet = RecvBytes(revBuffer, 4, 4, dwTimeoutMs);
        wDataLen = (revBuffer[6] & 0xFF) * 256 + (revBuffer[7] & 0xFF);
//        Log.e("wDataLen", wDataLen+"---");
        byRet = RecvBytes(revBuffer, 8, wDataLen + 1, dwTimeoutMs);
        if (wDataLen + 1 != byRet) {
            return ErrorDefine.RECV_PACKET_ERROR;
        }
        pwPacketetLen[0] = wDataLen;
        byte[] temp = new byte[wDataLen + 7];
        System.arraycopy(revBuffer, 1, temp, 0, temp.length);
//        Log.e("temp", ByteTool.bytearrayToHexString(temp,temp.length));
        if (revBuffer[wDataLen + 8] != (byte) cr_bcc(temp.length, temp)) {
            return ErrorDefine.RECV_PACKET_ERROR;
        }
        ;
        Log.e("all_rev", ByteTool.bytearrayToHexString(revBuffer, wDataLen + 9));
        return 0;

    }

    public boolean isOpen() {

        return isOpen;
    }

    public void PowerOn() {

//        rkGpioControlNative.ControlGpio(rkGpioControlNative.RK30_PIN0_PC4, 1);

    }

    public void PowerOff() {
        //  rkGpioControlNative.ControlGpio(rkGpioControlNative.RK30_PIN0_PC4, 0);

    }

    public void lightOn(){

        // rkGpioControlNative.ControlGpio(rkGpioControlNative.FINGERPRINT_LIGHT, 1);

    }
    public void lightOff(){

        // rkGpioControlNative.ControlGpio(rkGpioControlNative.FINGERPRINT_LIGHT, 0);

    }

    public synchronized byte[] TC_Send(byte head, byte[] data) {
        byte[] Complete = new byte[data.length + 8];
        byte[] temp = new byte[data.length + 6];
        Complete[0] = 0x7E;
        Complete[1] = 0x42;
        Complete[2] = head;
        Complete[3] = 0x00;
        Complete[4] = 0x00;
        Complete[5] = (byte) (data.length / 256);
        Complete[6] = (byte) (data.length % 256);
        System.arraycopy(data, 0, Complete, 7, data.length);
        System.arraycopy(Complete, 1, temp, 0, temp.length);
        Complete[data.length + 7] = ((byte) cr_bcc(temp.length, temp));
        Log.e("TCsend:", ByteTool.bytearrayToHexString(Complete, data.length + 8));
        writeFlush(Complete, data.length + 8);
        return Complete;
    }

    private int cr_bcc(int len, byte[] data) {
        int temp = 0;
        for (int i = 0; i < len; i++) {
            temp ^= data[i];
        }
        return temp;
    }


}
